from django.shortcuts import render
from rest_framework.exceptions import APIException
from rest_framework.viewsets import GenericViewSet
from .models import User
from .serializer import RegisterSerializer, MulLoginSerializer, SMSLoginSerializer
from utils.common_reponse import APIResponse
from rest_framework.decorators import action
from libs.tx_sms import get_code, send_sms as sms
from django.core.cache import cache
from threading import Thread


# 关于用户的所有接口
class UserView(GenericViewSet):
    serializer_class = MulLoginSerializer

    @action(methods=['GET'], detail=False, url_path='mobile')
    def check_mobile(self, request, *args, **kwargs):
        try:
            mobile = request.query_params.get('mobile', None)  # query_params:传递 URL中携带的参数
            User.objects.get(mobile=mobile)  # get:有且只有一条，正常往下执行，如果没有或多条，抛出异常
            return APIResponse(msg='手机号审核通过', is_exisit=True)
        except Exception as e:
            # raise APIException(detail='手机号不存在')
            return APIResponse(msg='手机号不存在', is_exisit=False)

    @action(methods=['POST'], detail=False)
    def send_sms(self, request, *args, **kwargs):
        '''
        1 安全性问题--最好要加密 请求体：{mobile:手机号,sign=md5(mobile+盐)}
        2 验证码要保存  保存到哪里？之前保存到session中，现在不用session，唯一标识是这个用户
            -缓存[django自带]：放到缓存中，key值唯一，使用手机号作为key值
        3 耗时操作，使用异步： 开启一条新线程负责发送短信
        4 最好写个频率控制，一分钟只能发一次--》现在手机号
        '''
        # 1 取出前端传入的手机号
        mobile = request.data.get('mobile')
        # 2 生成验证码 --问题：验证码需要保存
        code = get_code()
        cache.set(f'sms_{mobile}', code, 5 * 60)  # key值唯一,过期时间是5分钟
        # 3 调用发送短信 --》同步发送 --》要一直等 ，比较耗时间
        res = sms(code, mobile)

        # # 4 如果成功，返回给前端‘成功’，失败返回给前端失败
        # if res:
        #     return APIResponse(msg='短信发送成功')
        # else:
        #     return APIResponse(code=101, msg='短信发送失败')

        # 4 异步发送短信 --》多线程--》我没无法确定发送成功或失败
        t = Thread(target=sms, args=[code, mobile])
        t.start()
        return APIResponse(msg='短信已发送')

    # 多方式登陆 和 手机号验证码登陆，用的序列化类不一样
    def get_serializer_class(self):
        if self.action == 'sms_login':
            return SMSLoginSerializer
        else:
            return super().get_serializer_class()

    # 封装 --> 不用加装饰器
    def login(self, request, *args, **kwargs):
        # 1 实例化得到一个序列化类的对象  # request.data={mobile:手机号，code：1234}
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        username = serializer.context.get('username')
        token = serializer.context.get('token')
        icon = serializer.context.get('icon')
        return APIResponse(username=username, token=token, icon=icon)

    @action(methods=['POST'], detail=False)
    def mul_login(self, request, *args, **kwargs):
        return self.login(request, *args, **kwargs)

    @action(methods=['POST'], detail=False)
    def sms_login(self, request, *args, **kwargs):
        return self.login(request, *args, **kwargs)

    # @action(methods=['POST'], detail=False)
    # def mul_login(self, request, *args, **kwargs):
    #     # 1 实例化得到一个序列化的对象
    #     serializer = self.get_serializer(data=request.data)
    #     # 2 执行序列化类的校验方法
    #     serializer.is_valid(raise_exception=True)
    #     # 3 校验通过，从序列化类的对象中取出 token,username,icon
    #     username = serializer.context.get('username')
    #     token = serializer.context.get('token')
    #     icon = serializer.context.get('icon')
    #     # 4 返回给前端
    #     return APIResponse(username=username, token=token, icon=icon)
    #
    #
    # @action(methods=['POST'], detail=False)
    # def sms_login(self, request, *args, **kwargs):
    #     # 1 实例化得到一个序列化类的对象  # request.data={mobile:手机号，code：1234}
    #     serializer = self.get_serializer(data=request.data)
    #     serializer.is_valid(raise_exception=True)
    #     username = serializer.context.get('username')
    #     token = serializer.context.get('token')
    #     icon = serializer.context.get('icon')
    #     return APIResponse(username=username, token=token, icon=icon)


class RegisterView(GenericViewSet):
    serializer_class = RegisterSerializer

    @action(methods=['POST'], detail=False)
    def register(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return APIResponse(msg='注册成功，请登录')
